#include "../../include/redis/loginredis.h"

LoginRedis::LoginRedis()
{
}

LoginRedis::~LoginRedis()
{
}

void LoginRedis::redis_callback(WFRedisTask *task)
{
    LoginRedis *self = (LoginRedis *)task->user_data;
    self->isFinished = true;
    protocol::RedisValue val;
    task->get_resp()->get_result(val);
    if (!val.is_array() || val.arr_size() == 0)
    {
        self->vb.notify_one();
        return;
    }
    self->user_is_in_redis = true;
    self->m_pwd = val.arr_at(0).string_value();
    self->m_token = val.arr_at(1).string_value();
    self->vb.notify_one();
}

void LoginRedis::redis_newExpireUser_callback(WFRedisTask *task)
{
    Arg *arg = (Arg *)task->user_data;
    arg->m_locker.lock();
    ++arg->counter;
    arg->m_locker.unlock();
    if (arg->counter >= 2)
    {
        auto end_task_user_name = WFTaskFactory::create_redis_task(kRedis_url, 1, nullptr);
        auto end_task_user_token = WFTaskFactory::create_redis_task(kRedis_url, 1, nullptr);
        end_task_user_token->get_req()->set_request("EXPIRE", {arg->m_token, arg->m_kExpireTime});
        end_task_user_name->get_req()->set_request("EXPIRE", {arg->m_user.getUserName(), arg->m_kExpireTime});
        end_task_user_name->start();
        end_task_user_token->start();
        delete arg;
    }
}

bool LoginRedis::userIsInRedis(const std::shared_ptr<User> &user)
{
    WFRedisTask *task = WFTaskFactory::create_redis_task(kRedis_url, 1, redis_callback);
    task->get_req()->set_request("HGETALL", {user->getUserName()});
    task->user_data = this;
    task->start();
    std::unique_lock<std::mutex> lck(locker);
    while (!isFinished)
        vb.wait(lck);
    return user_is_in_redis;
}

void LoginRedis::resetExpireTime(const std::shared_ptr<User> &user)
{
    WFRedisTask *Expire_user_name = WFTaskFactory::create_redis_task(kRedis_url, 1, nullptr);
    WFRedisTask *Expire_user_token = WFTaskFactory::create_redis_task(kRedis_url, 1, nullptr);
    Expire_user_token->get_req()->set_request("EXPIRE", {m_token, kExpireTime});
    Expire_user_name->get_req()->set_request("EXPIRE", {user->getUserName(), kExpireTime});
    Expire_user_name->start();
    Expire_user_token->start();
}

void LoginRedis::newExpireUser(const std::shared_ptr<User> &user, const std::string &uuid)
{
    WFRedisTask *adduser_task = WFTaskFactory::create_redis_task(kRedis_url, 1, redis_newExpireUser_callback);
    WFRedisTask *addtoken_task = WFTaskFactory::create_redis_task(kRedis_url, 1, redis_newExpireUser_callback);
    Arg *arg = new Arg(*user, uuid, kExpireTime);
    adduser_task->user_data = arg;
    addtoken_task->user_data = arg;
    adduser_task->get_req()->set_request("HMSET", {user->getUserName(), user->getUserPwd(), uuid});
    addtoken_task->get_req()->set_request("HMSET", {uuid, user->getUserName(), user->getUserPwd()});
    adduser_task->start();
    addtoken_task->start();
}